package com.ray.depot.service.impl;

import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.ray.depot.service.StockDetailService;
import com.ray.depot.table.customMapper.SelectStockDetailMapper;
import com.ray.depot.table.dto.StockDetailDto;
import com.ray.depot.table.entity.StockDetail;
import com.ray.depot.table.entity.StockDetailExample;
import com.ray.depot.table.entity.StockDetailExample.Criteria;
import com.ray.depot.table.mapper.StockDetailMapper;
import com.xiaoleilu.hutool.util.ObjectUtil;
import com.xiaoleilu.hutool.util.StrUtil;
import com.zjhc.flyhong.common.function.enums.DeleteEnum;
import com.zjhc.flyhong.common.function.exception.BussinessException;
import com.zjhc.flyhong.common.function.operator.LoginUser;
import com.zjhc.flyhong.common.function.operator.PageDto;
import com.zjhc.flyhong.common.util.UUIDUtil;
import com.zjhc.flyhong.common.web.ErrorMsg;
import com.zjhc.flyhong.common.web.Result;
import com.zjhc.flyhong.common.web.SuccessMsg;
import com.zjhc.flyhong.common.web.base.BaseService;
@Service
public class StockDetailServiceImpl extends BaseService implements StockDetailService{
	/**日志对象**/
	private static Logger logger = Logger.getLogger(StockDetailServiceImpl.class);
	
	@Autowired
	private StockDetailMapper stockDetailMapper;
	@Autowired
	private SelectStockDetailMapper selectStockDetailMapper;

	@Transactional
	public Result<Object> addStockDetail(StockDetail params, LoginUser user) {
		Result<Object> result=null;
		result=new Result<Object>(0,SuccessMsg.OP_SUCCESS);
		params.setTenantId(user.getTenantId());
		params.setId(UUIDUtil.getUUID());
		params.setIsDelete(DeleteEnum.USE.getValue());
		this.setUserForAdd(params, user);
		int count=stockDetailMapper.insertSelective(params);
		if(count!=1){
			logger.error("StockDetailServiceImpl=>addStockDetail is error");
			throw new BussinessException(-1, ErrorMsg.INSERT_ERROR);
		}
		return result;
	}
	
	
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public StockDetail queryStockDetail(String id, LoginUser user) {
		return stockDetailMapper.selectByPrimaryKey(id);
		}
	
	
    @Transactional
	public Result<Object> updateStockDetail(StockDetail params, LoginUser user) {
		Result<Object> result=null;
		result=new Result<Object>(0,SuccessMsg.OP_SUCCESS);
		this.setUserForUpdate(params, user);
		int count=stockDetailMapper.updateByPrimaryKeySelective(params);
		if(count!=1){
			logger.error("StockDetailServiceImpl=>editStockDetail is error");
			throw new BussinessException(-1, ErrorMsg.INSERT_ERROR);
		}
		return result;
	}
    
    @Transactional
	public Result<Object> deleteStockDetail(String id, LoginUser user) {
		Result<Object> result=null;
		result=new Result<Object>(0,SuccessMsg.OP_SUCCESS);
		StockDetail params=new StockDetail();
		params.setId(id);
		params.setIsDelete(DeleteEnum.DELETE.getValue());
		this.setUserForUpdate(params, user);
		int count=stockDetailMapper.updateByPrimaryKeySelective(params);
		if(count!=1){
			logger.error("StockDetailServiceImpl=>deleteStockDetail is error");
			throw new BussinessException(-1, ErrorMsg.INSERT_ERROR);
		}
		return result;
	}
    
    @Transactional(propagation=Propagation.NOT_SUPPORTED)
	public PageDto<StockDetail> queryStockDetail(StockDetail params, PageDto<StockDetail> page, LoginUser user) {
		StockDetailExample example=new StockDetailExample();
		Criteria criteria = example.createCriteria();
		//超级管理员能查看全部
		if(!user.isSuperManager()){
			criteria.andTenantIdEqualTo(user.getTenantId());
		}
		criteria.andIsDeleteEqualTo(DeleteEnum.USE.getValue());
		this.setExamplePage(example, page);
		page.setTotal(stockDetailMapper.countByExample(example));
		page.setRecords(stockDetailMapper.selectByExample(example));
		return page;
	}
    
    @Transactional(propagation=Propagation.NOT_SUPPORTED)
   	public PageDto<StockDetailDto> querySelectStockDetail(StockDetailDto params, PageDto<StockDetailDto> page, LoginUser user) {
   	    params.setTenantId(user.getTenantId());
   	    params.setOrderByClause(page.getOrderBy());
   	    params.setLimitStart((page.getPage() - 1)  * page.getPageSize());
   	    params.setLimitEnd(page.getPageSize());
   	    params.setIsDelete(DeleteEnum.USE.getValue());
   		page.setTotal(selectStockDetailMapper.countByExample(params));
   		page.setRecords(selectStockDetailMapper.selectByExample(params));
   		return page;
   	}


	@Override
	public List<StockDetail> queryStockDetail(String materialId, String warchouseId, List<String> outids,
			LoginUser user) {
		StockDetailExample example=new StockDetailExample();
		Criteria criteria = example.createCriteria();
		criteria.andWarchouseIdEqualTo(warchouseId);
		criteria.andMaterialIdEqualTo(materialId);
		criteria.andIsDeleteEqualTo(DeleteEnum.USE.getValue());
		if(ObjectUtil.isNotNull(outids) && !outids.isEmpty()){
			criteria.andIdNotIn(outids);
		}
		example.setOrderByClause("IN_TIME");
		example.setLimitStart(0);
		example.setLimitEnd(5);
		return stockDetailMapper.selectByExample(example);
	}


	@Override
	@Transactional
	public int stockDetailOut(int outQuantity, StockDetail stockDetail, LoginUser user) {
		//可用数量
		 int useQuantity = stockDetail.getUseableQuantity();
		if(stockDetail.getUseableQuantity() <= outQuantity){
			//用完就删除记录
			stockDetail.setIsDelete(DeleteEnum.DELETE.getValue());
			stockDetail.setUseableQuantity(0);
		}else{
			stockDetail.setUseableQuantity(stockDetail.getUseableQuantity() - outQuantity);
		}
		//更新失败是否是 版本过期导致的
		try {
			updateStockDetailQuantity(stockDetail, user);
		} catch (Exception e) {
			//更新版本 在提交数据
			return addVersionUpdate(outQuantity,stockDetail,user);
		}
		
		return Math.max(0, outQuantity - useQuantity);
	}
	
	/**
     * 更新数量
     * @param stock
     * @param user
     */
	@Transactional
	private void updateStockDetailQuantity(StockDetail stock, LoginUser user) {
		StockDetailExample example=new StockDetailExample();
		Criteria criteria = example.createCriteria();
		criteria.andVersionNoEqualTo(stock.getVersionNo());//版本
		criteria.andIdEqualTo(stock.getId());
		stock.setVersionNo(stock.getVersionNo()+1);//版本加一
		this.setUserForUpdate(stock, user);
		int count=stockDetailMapper.updateByExampleSelective(stock, example);
		if(count != 1){
			logger.error("StockDetailServiceImpl=>updateStockDetailQuantity is error");
			throw new BussinessException(-1, ErrorMsg.UPDATE_ERROR);
		}
		
	}
	
	 /*
     * 更新版本然后提交数据
     */
	@Transactional
    private int addVersionUpdate(int outQuantity,StockDetail stock, LoginUser user) {
    	//查询仓库是否存在物料
		StockDetail newStock = this.queryStockDetail(stock.getId(), user);
		//记录已经被使用 返回出库数量
		if(StrUtil.equals(newStock.getIsDelete(), DeleteEnum.DELETE.getValue())){
			return outQuantity;
		}
		//版本号一样直接抛出异常
		if(stock.getVersionNo() ==  newStock.getVersionNo()){
			return outQuantity;
		}
		int useQuantity = newStock.getUseableQuantity();
		if(newStock.getUseableQuantity() <= outQuantity){
			//用完就删除记录
			newStock.setIsDelete(DeleteEnum.DELETE.getValue());
			newStock.setUseableQuantity(0);
		}else{
			newStock.setUseableQuantity(newStock.getUseableQuantity() - outQuantity);
		}
		//更新失败是否是 版本过期导致的
		try {
			updateStockDetailQuantity(newStock, user);
		} catch (Exception e) {
			//更新版本 在提交数据
		  return addVersionUpdate(outQuantity,newStock,user);
		}
		return Math.max(0, outQuantity - useQuantity);
	}

}
